﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Xml.Serialization;
using System.IO;
using System.Runtime.Serialization;
using ITAP.ShprossesBuilder.Modelling.Measurement;
using System.Runtime.Serialization.Formatters.Binary;
using System.Reflection;
using System.Windows.Forms;

namespace ITAP.ShprossesBuilder.Editor
{
    [Serializable]
    public class Preferences : ICloneable
    {
        private int splitterOffset = 130;

        public int SplitterOffset
        {
            get { return splitterOffset; }
            set { splitterOffset = value; }
        }
        private Orientation materialsTabOrientation = Orientation.Horizontal;

        public Orientation MaterialsTabOrientation
        {
            get { return materialsTabOrientation; }
            set { materialsTabOrientation = value; }
        }

        private double minimumShprossLength;

        public double MinimumShprossLength
        {
            get { return minimumShprossLength; }
            set { minimumShprossLength = value; }
        }

        private bool showShprossSnaps = true;

        public bool ShowShprossSnaps
        {
            get { return showShprossSnaps; }
            set { showShprossSnaps = value; }
        }
        private int thumbnailSize;

        public int ThumbnailSize
        {
            get { return thumbnailSize; }
            set { thumbnailSize = value; }
        }
        private int historyDepth;

        public int HistoryDepth
        {
            get { return historyDepth; }
            set { historyDepth = value; }
        }

        private DimensionsPreferences editorDimensions;

        public DimensionsPreferences EditorDimensions
        {
            get { return editorDimensions; }
            set { editorDimensions = value; }
        }

        private DimensionsPreferences draftDimensions;

        public DimensionsPreferences DraftDimensions
        {
            get { return draftDimensions; }
            set { draftDimensions = value; }
        }

        public Preferences()
        {
            this.EditorDimensions = new DimensionsPreferences();
            this.DraftDimensions = new DimensionsPreferences();
        }

        public void Save(string path)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(Preferences));
            Stream stream = File.Open(path, FileMode.Create);
            serializer.Serialize(stream, this);
            stream.Close();
        }

        public static Preferences Load(string path)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(Preferences));
            Preferences preferences;
            Stream stream;
            try
            {
                stream = File.Open(path, FileMode.Open);             
            }
            catch(FileNotFoundException ex)
            {
                preferences = Preferences.LoadDefault();
                stream = File.Open(path, FileMode.Create);
                serializer.Serialize(stream, preferences);
                stream.Close();
                return preferences;
            }

            preferences = (Preferences)serializer.Deserialize(stream);
            
            stream.Close();
            return preferences;
        }

        public static Preferences LoadDefault()
        {
            Preferences preferences = new Preferences();
            preferences.MaterialsTabOrientation = Orientation.Horizontal;
            preferences.EditorDimensions.Font = new Font("Arial", 8);
            preferences.DraftDimensions.Font = new Font("Arial", 12);
            preferences.MinimumShprossLength = 40;

            preferences.ThumbnailSize = 20;
            preferences.HistoryDepth = 30;           

            return preferences;
        }

        #region ICloneable Members

        public object Clone()
        {
            BinaryFormatter formatter = new BinaryFormatter();
            MemoryStream stream = new MemoryStream();
            formatter.Serialize(stream, this);
            stream.Seek(0, SeekOrigin.Begin);
            object clone = formatter.Deserialize(stream);
            stream.Close();
            return clone;
        }

        #endregion
    }

    public enum ViewSeparately
    {
        True,
        False,
        Disabled
    }

    [Serializable]
    public class DimensionsPreferences
    {
        [XmlIgnore]
        public Font Font
        {
            get
            {
                return proxyFont.ToFont();
            }
            set
            {
                proxyFont = new ProxyFont(value.FontFamily.Name, value.Size, value.Italic, value.Bold);
            }
        }

        private ProxyFont proxyFont;

        public ProxyFont ProxyFont
        {
            get { return proxyFont; }
            set { proxyFont = value; }
        }

        private DimensionPreferences modelDimensions;

        public DimensionPreferences ModelDimensions
        {
            get { return modelDimensions; }
            set { modelDimensions = value; }
        }
        private DimensionPreferences spacerDimensions;

        public DimensionPreferences SpacerDimensions
        {
            get { return spacerDimensions; }
            set { spacerDimensions = value; }
        }
        private DimensionPreferences shprossDimensions;

        public DimensionPreferences ShprossDimensions
        {
            get { return shprossDimensions; }
            set { shprossDimensions = value; }
        }
        private DimensionPreferences pinHolesDimensions;

        public DimensionPreferences PinHolesDimensions
        {
            get { return pinHolesDimensions; }
            set { pinHolesDimensions = value; }
        }

        public DimensionsPreferences()
        {
            modelDimensions = new DimensionPreferences("Размеры модели", DimensionType.NotDefined, Color.Black);
            shprossDimensions = new DimensionPreferences("Размеры профилей", DimensionType.NotDefined, Color.Black);
            spacerDimensions = new DimensionPreferences("Размеры рамки", DimensionType.InnerDimension, Color.Black);
            pinHolesDimensions = new DimensionPreferences("Размеры отверстий в рамке", DimensionType.InnerDimension, Color.Black);
            this.proxyFont = new ProxyFont("Arial", 8, false, false);
        }
    }

    [Serializable]
    public class DimensionPreferences
    {
        private string name;

        public string Name
        {
            get { return name; }
            set { name = value; }
        }

        [XmlIgnore]
        public Color Color
        {
            get 
            {
                return proxyColor.ToColor();
            }
            set 
            { 
                proxyColor = new ProxyColor(value.A, value.R, value.G, value.B);
            }
        }

        private ProxyColor proxyColor;
        
        public ProxyColor ProxyColor
        {
            get { return proxyColor; }
            set { proxyColor = value; }
        }

        private DimensionType dimensionType;

        public DimensionType DimensionType
        {
            get { return dimensionType; }
            set { dimensionType = value; }
        }

        public DimensionPreferences(string name, DimensionType dimensionType, Color color)
        {
            this.proxyColor = new ProxyColor(color.A, color.R, color.G, color.B);
            this.name = name;
            this.dimensionType = dimensionType;
        }

        public DimensionPreferences()
        {

        }

        public override string ToString()
        {
            return this.Name;
        }
    }

    [Serializable]
    public class ProxyColor
    {
        private int alpha;

        public int Alpha
        {
            get { return alpha; }
            set { alpha = value; }
        }
        private int r;

        public int R
        {
            get { return r; }
            set { r = value; }
        }
        private int g;

        public int G
        {
            get { return g; }
            set { g = value; }
        }
        private int b;

        public int B
        {
            get { return b; }
            set { b = value; }
        }

        public ProxyColor()
        {
        }

        public ProxyColor(int alpha, int r, int g, int b)
        {
            this.alpha = alpha;
            this.r = r;
            this.g = g;
            this.b = b;
        }

        public Color ToColor()
        {
            return Color.FromArgb(alpha, r, g, b);
        }   

    }
    [Serializable]
    public class ProxyFont
    {
        private float size;

        public float Size
        {
            get { return size; }
            set { size = value; }
        }
        private string family;

        public string Family
        {
            get { return family; }
            set { family = value; }
        }

        private bool isItalic;

        public bool IsItalic
        {
            get { return isItalic; }
            set { isItalic = value; }
        }
        private bool isBold;

        public bool IsBold
        {
            get { return isBold; }
            set { isBold = value; }
        }

        public ProxyFont()
        {
        }

        public ProxyFont(string fontFamily, float size, bool isItalic, bool isBold)
        {
            this.family = fontFamily;
            this.size = size;
            this.isItalic = isItalic;
            this.isBold = isBold;
        }

        public Font ToFont()
        {
            FontStyle style;
            if(isItalic && isBold)
                style = FontStyle.Italic | FontStyle.Bold;
            else if(isItalic)
                style = FontStyle.Italic;
            else if(isBold)
                style = FontStyle.Bold;
            else
                return new Font(family, size);

            return new Font(family, this.size, style);
        }
    }

    public static class GlobalPreferences
    {
        private static Preferences preferences = new Preferences();

        public static Preferences Preferences
        {
            get { return GlobalPreferences.preferences; }
            set { GlobalPreferences.preferences = value; }
        }

        public static bool Debug = false;

        public static void Load(string path)
        {
            preferences = Preferences.Load(path);                        
        }
        public static void Save(string path)
        {
            preferences.Save(path);
        }
        public static void LoadFromDefaultLocation()
        {
            Assembly currentAssembly = Assembly.GetExecutingAssembly();
            string currentAssemblyLocation = Path.GetDirectoryName(currentAssembly.Location);
            GlobalPreferences.Load(currentAssemblyLocation + "\\" + "ShprossPreferences.xml");
        }

        public static void SaveToDefaultLocation()
        {
            Assembly currentAssembly = Assembly.GetExecutingAssembly();
            string currentAssemblyLocation = Path.GetDirectoryName(currentAssembly.Location);
            GlobalPreferences.Save(currentAssemblyLocation + "\\" + "ShprossPreferences.xml");
        }

    }
}
